/*
* Copyright (C) 2020 ~ 2024 chaigec All Rights Reserved.
*
* Author:     chaigec <chaigec@163.com>
* Maintainer: chaigec <chaigec@163.com>

 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
*/

#include "MkRtmpConumer.h"
#include "MkMedia/MkMediaSource.h"
#include "MkRtmpSession.h"
#include "MkFlv/MkFlvMuxer.h"

CMkRtmpConsume::CMkRtmpConsume()
    : CMkMediaConsume(MkMediaConsumeRtmp)
{

}

Uint32 CMkRtmpConsume::ConsumeEsPacket(CMkMediaSource* pSource, const MkEsPacket& EsPacket, Uint8* pBuf, Uint32 nLen)
{
    Uint32 nEsUsed = 0;
    Uint32 nUsed = 0;
    CMkBufferList EsBufferList;
    CMkRtmpConsumer *pRtmpConsumer = nullptr;
    CMkFlvMuxer::PacketEsPacket(pSource->GetVideoParam(), pSource->GetAudioParam(), EsPacket, pBuf, nLen, nEsUsed, EsBufferList, TRUE);
    MkMap<MkString, CMkMediaConsumer*>::iterator it = GetMapConsumer().begin();
    for (; it != GetMapConsumer().end(); it++) {
        pRtmpConsumer = dynamic_cast<CMkRtmpConsumer*>(it->second);
        if (!pRtmpConsumer) {
            continue;
        }
        if (pRtmpConsumer->IsFirstSend()) {
            CMkBufferList BufferList;
            MkEsPacket TmpEsPacket;
            nUsed = nEsUsed;

            CMkFlvMuxer::PacketScriptTag(pSource->GetVideoParam(), pSource->GetAudioParam(), pSource->m_FileSize, pSource->m_Duration, pBuf + nEsUsed, nLen - nEsUsed, nUsed, BufferList, TRUE, TRUE);

            pRtmpConsumer->ConsumeEsPacket(MkEsPacket(), BufferList);

            if (MkCodecUnknown != pSource->GetVideoParam().GetCodec()) {
                nUsed = nEsUsed;
                BufferList.Clear();
                TmpEsPacket.CodecType = pSource->GetVideoParam().GetCodec();
                CMkFlvMuxer::PacketVideoTagPreparation(pSource->GetVideoParam(), pBuf + nEsUsed, nLen - nEsUsed, nUsed, BufferList, TRUE);
                pRtmpConsumer->ConsumeEsPacket(TmpEsPacket, BufferList);
            }

            if (MkCodecUnknown != pSource->GetAudioParam().GetCodec()) {
                nUsed = nEsUsed;
                BufferList.Clear();
                TmpEsPacket.CodecType = pSource->GetAudioParam().GetCodec();
                CMkFlvMuxer::PacketAudioTagPreparation(pSource->GetAudioParam(), pBuf + nEsUsed, nLen - nEsUsed, nUsed, BufferList, TRUE);
                pRtmpConsumer->ConsumeEsPacket(TmpEsPacket, BufferList);
            }

            MkVector<MkCacheEsPacket>::const_iterator itCache = pSource->GetCacheEsPacket().begin();
            for (; itCache != pSource->GetCacheEsPacket().end(); itCache++) {
                MkEsPacket TmpEsPacket;
                CMkMediaUtil::ReadCachePacket(*itCache, TmpEsPacket);
                nUsed = nEsUsed;
                BufferList.Clear();
                CMkFlvMuxer::PacketEsPacket(pSource->GetVideoParam(), pSource->GetAudioParam(), TmpEsPacket, pBuf + nEsUsed, nLen - nEsUsed, nUsed, BufferList, TRUE);
                pRtmpConsumer->ConsumeEsPacket(TmpEsPacket, BufferList);
            }
            pRtmpConsumer->SetFirstSend(FALSE);
        }
        pRtmpConsumer->ConsumeEsPacket(EsPacket, EsBufferList);
    }
    return NoneError;
}

CMkRtmpConsumer::CMkRtmpConsumer(CMkRtmpSession* pRtmpSession)
    : CMkMediaConsumer(MkMediaConsumeRtmp)
    , m_pRtmpSession(pRtmpSession)
{

}

Uint32 CMkRtmpConsumer::ConsumeEsPacket(const MkEsPacket& EsPacket, const CMkBufferList& BufferList)
{
    AddSendBytes(BufferList.GetTatolLen());
    if (m_pRtmpSession) {
        m_pRtmpSession->SendFlvStream(EsPacket, BufferList);
    }
    return NoneError;
}

void CMkRtmpConsumer::Release()
{
    if (m_pRtmpSession) {
        m_pRtmpSession->Close();
    }
}

CMkRtmpConsumer::~CMkRtmpConsumer()
{
    m_pRtmpSession = nullptr;
}

CMkRtmpConsume::~CMkRtmpConsume()
{

}